package com.yanjue.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yanjue.bo.BookPreviousAndNextChapterNode;
import com.yanjue.common.entity.Book;
import com.yanjue.common.entity.BookChapter;
import com.yanjue.common.redisKey.RedisBookKey;
import com.yanjue.common.redisKey.RedisExpire;
import com.yanjue.common.redisKey.RedisService;
import com.yanjue.common.util.Result;
import com.yanjue.common.util.ResultUtil;
import com.yanjue.mapper.BookChapterMapper;
import com.yanjue.mapper.BookMapper;
import com.yanjue.service.BookChapterService;
import com.yanjue.vo.BookChapterListVO;
import com.yanjue.vo.BookChapterReadVO;
import com.yanjue.vo.BookChapterVO;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
* @author yanju
* @description 针对表【book_chapter】的数据库操作Service实现
* @createDate 2025-01-16 12:33:44
*/
@Service
public class BookChapterServiceImpl extends ServiceImpl<BookChapterMapper, BookChapter>
    implements BookChapterService {

    @Autowired
    private RedisService redisService;
    @Autowired
    private BookChapterMapper bookChapterMapper;
    @Autowired
    private BookMapper bookMapper;
    /**
     * 查询图书章节列表信息
     * @param bookId
     * @return chapterVOS 章节集合
     */
    @Override
    public Result getBookChapterListByBookId(String bookId) {
        Book book = bookMapper.selectById(bookId);
        if (null == book){
            //没有此书
            return ResultUtil.notFound().buildMessage("找不到此书");
        }
        String key = RedisBookKey.getBookChapterListKey(bookId);
        List<BookChapterListVO> chapterVOS = redisService.getCacheForList(key, BookChapter.class);
        if (ObjectUtils.isEmpty(chapterVOS)){
            //查db 获取书的章节集合
            List<BookChapter> bookChapters = this.bookChapterMapper.selectList(new LambdaQueryWrapper<BookChapter>()
                    .eq(BookChapter::getBookId, bookId));
            if (!bookChapters.isEmpty()) {
                chapterVOS = new ArrayList<>();
                //转化
                for (BookChapter bookChapter : bookChapters) {
                    BookChapterListVO vo = new BookChapterListVO();
                    BeanUtils.copyProperties(bookChapter,vo);
                    chapterVOS.add(vo);
                }
                //存缓存
                this.redisService.setExpireCache(key,chapterVOS, RedisExpire.MONTH);
            }
        }
        return ResultUtil.success(chapterVOS);
    }

    /**
     * 阅读章节 章节阅读 ：  第一章 只有下一章没有上一章
     *                      中间，有上下章
     *                      最后一章 只有上一章没有下一章
     *          方便读取，上下相连 双向链表
     *          hash存取，key 章节ID，value 即链表内容
     *          TODO 修改章节后修改缓存， 找不到修改章节接口，，没有作者创作功能 可以添加限流防止雪崩
     * @param bookId
     * @param chapterId 章节ID(0获取首章节，-1获取末章节)
     * @return
     */
    @Override
    public Result<BookChapterReadVO> readChapter(String bookId, Integer chapterId) {
        //1.书是否存在
        Book book = bookMapper.selectById(bookId);
        if (null == book){
            return ResultUtil.notFound().buildMessage("找不到该书");
        }


        String key = RedisBookKey.getBookChapterNodeKey(Integer.valueOf(bookId));
        String field = chapterId.toString();

        if (chapterId == 0){
            field = "first";
        } else if (chapterId == -1){
            field = "last";
        }

        //2.获取当前章节的前后章节数据
        BookPreviousAndNextChapterNode chapterNode = this.getChapterNodeData(book.getId(), field);
        if (chapterNode == null){
            //2.1.获取不到默认查询首章节
            field = "first";
            chapterNode = this.getChapterNodeData(book.getId(), field);
            if (chapterNode == null){
                return ResultUtil.notFound().buildMessage("本书没有任何章节");
            }
        }
        // 如果当前章被锁定，返回明确提示
        /*if (chapterNode.) {
            return ResultUtil.locked().buildMessage("本章暂未解锁，请等待作者发布！");
        }*/

        //3.获取当前章节内容
        String content = this.getChapterContent(bookId, chapterNode.getId());
        BookChapterVO current = new BookChapterVO(chapterNode.getId(),chapterNode.getName(),content);

        //4.设置上一章、下一章
        BookChapterVO pre = null;
        BookChapterVO next = null;
        BookPreviousAndNextChapterNode pre1 = chapterNode.getPre();
        if (pre1 != null){
            pre = new BookChapterVO(pre1.getId(), pre1.getName(),"");
        }
        if (chapterNode.getNext() != null){
            next = new BookChapterVO(chapterNode.getNext().getId(),chapterNode.getNext().getName(),"");
        }

        //封装
        BookChapterReadVO result = new BookChapterReadVO();
        result.setPre(pre);
        result.setNext(next);
        result.setCurrent(current);
        return ResultUtil.success(result);
    }

    /**
     * 获取章节内容
     * @param bookId
     * @param chapterId
     * @return
     */
    private String getChapterContent(String bookId, Integer chapterId) {
        String content = "";
        BookChapter chapter;
        String key = RedisBookKey.getBookChapterKey(bookId);
        String field = chapterId.toString();
        chapter = this.redisService.getHashVal(key, field, BookChapter.class);
        if (chapter == null) {
            chapter = this.bookChapterMapper.selectById(chapterId);
            if (chapter != null) {
                this.redisService.setHashValExpire(key, field ,chapter, RedisExpire.HOUR);
            }
        }
        if (chapter != null) {
            content = chapter.getContent();
        }
        return content;
    }

    /**
     *获取前后章节节点数据链表
     * @param bookId
     * @param field
     * @return
     */
    private BookPreviousAndNextChapterNode getChapterNodeData(Integer bookId, String field) {
        //1.缓存获取
        String key = RedisBookKey.getBookChapterNodeKey(bookId);
        BookPreviousAndNextChapterNode chapterNode = redisService.getHashObject(key, field, BookPreviousAndNextChapterNode.class);
        if (chapterNode != null){
            return chapterNode;
        }

        //2.获取章节列表
        List<BookChapter> chapterList = this.bookChapterMapper.selectList(new LambdaQueryWrapper<BookChapter>()
                .eq(BookChapter::getBookId, bookId));
        if (chapterList.isEmpty()){
            return null;
        }

        HashMap<String,BookPreviousAndNextChapterNode> map = new HashMap<>();
        // 上一章节节点数据
        BookPreviousAndNextChapterNode pre = null;
        // TODO 锁章 涉及 会员或者充值购买功能 或者也可以全免费类似番茄 bug
        for (int i = 1; i <= chapterList.size(); i++) {
            BookChapter chapter = chapterList.get(i - 1);
            //锁章 锁的话可以返回前端说是未解锁，可以充值解锁或者会员解锁或者等待作者发布等等
            if (chapter.getLockStatus()){
                if (i >= chapterList.size()) {
                    break;
                }
                chapter = chapterList.get(i);
            }

            BookPreviousAndNextChapterNode curr = new BookPreviousAndNextChapterNode(chapter.getId(), chapter.getName());
            if (pre != null) {
                curr.setPre(pre);
                pre.setNext(curr);
                map.put(pre.getId().toString(), pre);
            }
            // 存储节点数据
            pre = curr;
            map.put(curr.getId().toString(), curr);
        }

        // 最后一 章节
        map.put("last", pre);
        this.redisService.setHashValsExpire(key, map, RedisExpire.MONTH);

        //3.
        return map.get(field);
    }
}




